package com.numturnmoney;
import java.util.Scanner;

/**
 * @Description: 将浮点数转换成人民币读法字符串，例如将1006.333转换成为壹仟零陆元叁角三分。
 * @author: Jacky
 * @date: 2021.10.12
 */
public class NumTurnMoney {

    //汉字数组
    private final String[] chineseArr = new String[]{"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
    //单位数组
    private final String[] unitArr = new String[]{"仟","佰","拾"};

    public static void main(String[] args) {
        NumTurnMoney numturnmoney = new NumTurnMoney();
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个数字（可为浮点数）将转换成人民币读法字符串：");
        double num = 0.0;
        num = input.nextDouble();
        String result = numturnmoney.numTurnChinese(num);
        System.out.println(result);

    }

    /**
     * @deprecated:  四位数的字符串转人民币读法
     * @param numStr: 将整个数字字符串分割成每4位数一组后的，数字字符串
     * @return: 当前4位数字转换成人民币读法后的，汉字字符串
     * @exception/throws:
     * @author: 我是作者Jacky
     * @date:   2021/10/12
     */
    public String numStrToChineseStrIntPartCore(String numStr) {
        //保存结果，初始化为空
        String result = "";
        //获取numStr的长度
        int len = numStr.length();
        //补零操作
        //位数小于4位就在前面补零
        if(len < 4)
        {
            String[] addZeroStr = {"0","00","000"};
            //4减去长度等于需要补零的个数，要补充的0在addZeroStr中，需要使用数组下标，所以再减一
            numStr = addZeroStr[4-len-1] + numStr;
        }
        //更新长度，len==4
        len = numStr.length();
        //扫描至第一个不为0的字符
        int i=0;
        //i表示下标，下标小于长度，并且截取字符串的每一个字符和“0”比较
        while(i < len && numStr.charAt(i)-'0'==0){
            i++;
        }
        //如果4个数都是0，那么直接输出一个0，并返回结果。
        if(i==len){
            result += "零";
            return result;
        }
        //四个数不都为0的情况，扫描4个数
        for(;i < len; i++){
            //charAt()返回的是一个char类型的值，char类型的值，可以直接相减（自动转换成ASCLL码值相减）
            //获取的单个字符，和0的ASCLL码值相差多少，数值就是多少。
            int num = numStr.charAt(i) - '0';
            //不是末尾且不为0
            if( i != len-1 && num != 0){
                //直接映射汉字和单位，num汉字的下标，i单位的下标
                result += chineseArr[num] + unitArr[i] ;
            } else {
                //若当前结果字符串中最后一位不是“零”，且数字串最后一位不是数字0 这样对中间2个零的只添加一个“零”如1003
                if( result.length()>0 && result.charAt(result.length()-1) != '零'
                        && numStr.charAt(len-1)-'0'!= 0) {
                    //四位中第二，三位至少有一个为0且最后一位数字不为0 如1003 则为一千零三
                    if((i == 1||i == 2) && num == 0){
                        result += "零";
                    }
                }
                //是最后一位，且数字不为0 不加单位
                if( i == len - 1 && num != 0) {
                    result += chineseArr[num];
                }
            }
        }
        //返回结果字符串
        return  result;
    }

    /**
     * @deprecated:  获取数字字符串有效位
     * @param str: 整个数字字符串
     * @return: 返回第一个不为0的数字的位置
     * @exception/throws:
     * @author: 我是作者Jacky
     * @date:   2021/10/12
     */

    public int getValidStrLen(String str) {
        //起始位置
        int start = 0;
        //当前数字字符串长度
        int len = str.length();
        //从第一个开始遍历，如果为0，就检查下一个，不为0就找到第一个有效数字
        while(start < len  && str.charAt(start) =='0'){
            start++ ;
        }
        //start++，表示了当前无效位的个数，计算的时候分成4个数字一组
        return 4 - start;
    }

    /**
     * @deprecated:  将12位整数部分数字转为汉字字符串
     * @param numStr: 整个数字字符串
     * @return: 整个数字字符串转换为人民币读法后的汉字字符串
     * @exception/throws:
     * @author: 我是作者Jacky
     * @date:   2021/10/12
     */

    public String numStrToChineseStrIntNum(String numStr) {
        //获取整个数字字符串的总长度
        int len = numStr.length();
        //判断输入的数字字符串分成4位1组，能分成几份
        int partNum = (len%4==0) ? (len/4) : (len/4)+1;
        //分别定义亿，万，元单位字符串
        String strYi="",strWan="",strYuan="";
        //12位以内的数字字符串最多能分成三部分
        String firstStr,secondStr,thirdStr;
        //用于保存分割成4位后的数字字符串有效字符串长度，去除0
        int tempLen;
        boolean fourValidBitYuan = false ; //判断第三部分是否为4位
        switch(partNum) {
            //只有1部分，就是xxx元
            case 1:
                //如果只有1部分，就不用分割，直接转换
                strYuan += numStrToChineseStrIntPartCore(numStr);
                break;
            //有2部分，就是 xxx万xxx元
            case 2:
                //注意 String.substring(beginindex,endIndex)中endindex不包含
                int endIndex = len - 4 ;
                //一部分一部分的截取
                firstStr = numStr.substring(0,endIndex);
                strWan += numStrToChineseStrIntPartCore(firstStr)+"万";
                secondStr = numStr.substring(endIndex,len);
                strYuan += numStrToChineseStrIntPartCore(secondStr);
                tempLen = getValidStrLen(secondStr);
                if(0 <tempLen && tempLen < 4 ){
                    strYuan = "零"+ strYuan;
                }
                break;
            //有3部分，就是 xxx亿xxx万xxx元
            case 3:
                int endIndex2 = len - 4;
                int endIndex1 = endIndex2 - 4;
                firstStr = numStr.substring(0,endIndex1);
                strYi +=  numStrToChineseStrIntPartCore(firstStr)+"亿";
                secondStr = numStr.substring(endIndex1,endIndex2);
                strWan += numStrToChineseStrIntPartCore(secondStr)+"万";
                tempLen = getValidStrLen(secondStr);
                //中间过程进行补零
                if(0< tempLen && tempLen<4 ) {
                    strWan = "零"+strWan;
                }
                thirdStr = numStr.substring(endIndex2,len);
                strYuan += numStrToChineseStrIntPartCore(thirdStr) ;
                tempLen = getValidStrLen(thirdStr);
                if(0 <tempLen && tempLen < 4 ){
                    strYuan = "零"+ strYuan;
                } else {
                    if( tempLen == 4) {
                        fourValidBitYuan = true;
                    }
                }
                break;
            default:
                break;
        }
        //对结果进行判断，如果万位和元位都为0
        if(strWan.equals("零万")) {
            //Str_wan为"零万"且元部分为4位。如12300001234中间需读出"零"
            if(fourValidBitYuan ){
                strWan = "零";
            }
            //否则就不添加
            else{
                strWan = "";
            }
        }
        if( strYuan.equals("零")){
            strYuan = "";
        }
        return strYi + strWan + strYuan + "元";
    }

    /**
     * @deprecated: 处理小数部分字符串，小数部分最多两位
     * @param floatStr: 小数部分字符串
     * @return: 返回小数部分转换成人民币读法的汉字字符串
     * @exception/throws:
     * @author: 我是作者Jacky
     * @date:   2021/10/12
     */

    public String numStrToChineseStrFloat(String floatStr) {
        String resultJiao = "",resultFen = "";
        //小数部分长度
        int len  = floatStr.length();
        //补零操作,位数小于两位，就在前面补0
        if(len < 2) {
            //和整数部分补位，同理
            String[] addZeroStr = {"0","00"};
            floatStr = addZeroStr[2-len-1] + floatStr;
        }
        //固定的两位，角和分
        for(int i=0 ; i < 2 ; ++i) {
            //获取当前的数值
            int num = floatStr.charAt(i) - '0';
            //当是小数部分第一位的时候
            if( i == 0) {
                //映射数值
                resultJiao += chineseArr[num] ;
                //如果不等于0，添加单位
                if( num != 0){
                    resultJiao += "角";
                }
            }
            //当是小数部分第二位的时候
            else {
                //判断不为0，映射数值，并添加单位
                if(num !=0){
                    resultFen += chineseArr[num]+"分";
                }
            }
        }
        //检查一次，当小数部分两个数都为0的时候
        if( resultFen.equals("") && (resultJiao.equals("零")||resultJiao.equals("零角"))){
            resultJiao = "";
        }
        return resultJiao + resultFen;
    }

    /**
     * @deprecated:  用于合并功能的函数
     * @param num: 传入浮点数
     * @return: java.lang.String
     * @exception/throws:
     * @author: 我是作者Jacky
     * @date:   2021/10/12
     */

    public String numTurnChinese(double num){
        //将浮点数直接强转成长整型，得到整数部分
        long intNum = (long)num;
        //得到小数部分
        long floatNum = Math.round((num - intNum)*100);
        //得到两部分转中文的组合字符串
        String result = numStrToChineseStrIntNum(""+intNum)+numStrToChineseStrFloat(""+floatNum);
        return result.replace("壹拾","拾");
    }
}
